/*
 * Copyright (c) 2006-2021, Ulandlink Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-08-18     lfz         first version
 */

#include <fal.h>
#include "sfud_port.h"
#include "drv_spi_flash.h"

#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define FAL_USING_NOR_FLASH_DEV_NAME             "norflash0"
#endif

static int init(void);
static int read(long offset, uint8_t *buf, size_t size);
static int write(long offset, const uint8_t *buf, size_t size);
static int erase(long offset, size_t size);

static sfud_flash_t sfud_dev = NULL;
struct fal_flash_dev nor_flash0 =
{
	.name       = FAL_USING_NOR_FLASH_DEV_NAME,
	.addr       = 0,
	.len        = 16 * 1024 * 1024,
	.blk_size   = 4096,
	.ops        = {init, read, write, erase},
	.write_gran = 1
};

static int init(void)
{

#ifdef RT_USING_SFUD
	sfud_dev = rt_sfud_flash_find(SPI_DEV_NAME);
#else
	/* bare metal platform */
	extern sfud_flash sfud_norflash0;
	sfud_dev = &sfud_norflash0;
#endif

	if (NULL == sfud_dev){
		return -1;
	}

	/* update the flash chip information */
	nor_flash0.blk_size = sfud_dev->chip.erase_gran;
	nor_flash0.len = sfud_dev->chip.capacity;

	return 0;
}

static int read(long offset, uint8_t *buf, size_t size)
{
	assert(sfud_dev);
	assert(sfud_dev->init_ok);
	if (sfud_read(sfud_dev, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS){
		return -1;
	}

	return size;
}

static int write(long offset, const uint8_t *buf, size_t size)
{
	assert(sfud_dev);
	assert(sfud_dev->init_ok);
	if (sfud_write(sfud_dev, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS){
		return -1;
	}

	return size;
}

static int erase(long offset, size_t size)
{
	assert(sfud_dev);
	assert(sfud_dev->init_ok);
	if (sfud_erase(sfud_dev, nor_flash0.addr + offset, size) != SFUD_SUCCESS){
		return -1;
	}

	return size;
}


